#include "ml20dll.h"

static DWORD WINAPI startvideothread( INJDATA *injdata )
{
    injdata->vfwdll = injdata->LoadLibraryX( injdata->vfw );

    injdata->ICInstall = (BOOL (__stdcall *) (DWORD, DWORD, LPARAM, LPSTR, UINT)) injdata->GetProcAddress(injdata->vfwdll, injdata->icinstall);
    injdata->ICOpen = (HIC (__stdcall *) (DWORD, DWORD, UINT)) injdata->GetProcAddress(injdata->vfwdll, injdata->icopen);
    injdata->ICDecompress = (DWORD (__cdecl *) (HIC, DWORD, LPBITMAPINFOHEADER, LPVOID, LPBITMAPINFOHEADER, LPVOID)) injdata->GetProcAddress(injdata->vfwdll, injdata->icdecompress);
    injdata->ICClose = (LRESULT (__stdcall *) (HIC)) injdata->GetProcAddress(injdata->vfwdll, injdata->icclose);
    injdata->ICSendMessage = (LRESULT (__stdcall *)( HIC hic, UINT wMsg, DWORD dw1, DWORD dw2 )) injdata->GetProcAddress( injdata->vfwdll, injdata->icsendmessage );
    injdata->ICRemove = (BOOL (__stdcall *)( DWORD fccType, DWORD fccHandler, UINT wFlags )) injdata->GetProcAddress( injdata->vfwdll, injdata->icremove );

    injdata->ICInstall( ICTYPE_VIDEO, FOURCC_ML20, injdata->ml20proc, NULL, ICINSTALL_FUNCTION );

    injdata->hIC = injdata->ICOpen( ICTYPE_VIDEO, FOURCC_ML20, ICMODE_DECOMPRESS );
    injdata->ICSendMessage( injdata->hIC, ICM_DECOMPRESS_BEGIN, (DWORD) &injdata->ML20,  (DWORD) &injdata->BITM );

    injdata->ICRemove( ICTYPE_VIDEO, FOURCC_ML20, 0 );
    return 0;
}

static DWORD WINAPI decodevideothread( INJDATA *injdata )
{
    injdata->ICDecompress( injdata->hIC, 0, &(injdata->ML20), injdata->in, &(injdata->BITM), injdata->remoteout );

    return 0;
}

static DWORD WINAPI endvideothread( INJDATA *injdata )
{
    injdata->ICSendMessage( injdata->hIC, ICM_DECOMPRESS_END, 0, 0 );

    injdata->ICClose( injdata->hIC );

    injdata->FreeLibrary( injdata->vfwdll );

    return 0;
}

static void dummyfunc( void )
{
    ;
}

int svt_address( void )
{
    return( (int) startvideothread );
}

int dvt_address( void )
{
    return( (int) decodevideothread );
}

int evt_address( void )
{
    return( (int) endvideothread );
}

int svt_size( void )
{
    return( (LPBYTE) decodevideothread - (LPBYTE) startvideothread );
}

int dvt_size( void )
{
    return( (LPBYTE) endvideothread - (LPBYTE) decodevideothread );
}

int evt_size( void )
{
    return( (LPBYTE) dummyfunc - (LPBYTE) endvideothread );
}
